#include "pcf8574.h"
#include <qdebug.h>
#include <windows.h>
#include "CH341DLL.H"


PCF8574::PCF8574(QObject *parent) : QObject(parent)
{
}

BOOL WINAPI PCF8574::PCF8574_WriteIO(  // 输出PCF8574的I/O
    ULONG			iIndex,  // 指定CH341设备序号
    ULONG			iDeviceAddr,  // 设备地址,最低位为命令方向位
    ULONG			iOutByte)  // 准备写出的I/O数据
{
//    ULONG	mLength, mInLen;
    BOOL isack = false;
    UCHAR	mBuffer_Start[ mCH341_PACKET_LENGTH ];
    UCHAR	mBuffer_Data [ mCH341_PACKET_LENGTH ];
//    UCHAR	mBuffer_Stop [ mCH341_PACKET_LENGTH ];
    ULONG	Start_Length;
    Start_Length = 5;
    mBuffer_Start[ 0 ] = mCH341A_CMD_I2C_STREAM;  // 命令码
    mBuffer_Start[ 1 ] = mCH341A_CMD_I2C_STM_STA;  // 产生起始位
    mBuffer_Start[ 2 ] = static_cast<UCHAR>( mCH341A_CMD_I2C_STM_OUT | 2 );  // 输出数据,位5-位0为长度,2字节
    mBuffer_Start[ 3 ] = static_cast<UCHAR>( iDeviceAddr & 0xFE );  // 设备地址,写操作
    mBuffer_Start[ 4 ] = mCH341A_CMD_I2C_STM_END;  // 当前包提前结束
    CH341WriteData( iIndex, mBuffer_Start, &Start_Length );
    mBuffer_Data[0] = static_cast<UCHAR>(iOutByte);  // I/O数据
    isack = IIC_OutByteCheckAck(iIndex, mBuffer_Data[0]);
    qDebug() << "ack=" << isack;
    return (isack);
}

BOOL WINAPI	PCF8574::PCF8574_WriteIONoack(  // 输出PCF8574的I/O
    ULONG			iIndex,  // 指定CH341设备序号
    ULONG			iDeviceAddr,  // 设备地址,最低位为命令方向位
    ULONG			iOutByte )  // 准备写出的I/O数据
{
    // 可以直接用CH341StreamI2C( iIndex, 2, mBuffer, 0, NULL )实现
    UCHAR	mBuffer[ mCH341_PACKET_LENGTH ];
    ULONG	mLength;
    mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM;  // 命令码
    mBuffer[ 1 ] = mCH341A_CMD_I2C_STM_STA;  // 产生起始位
    mBuffer[ 2 ] = static_cast<UCHAR>( mCH341A_CMD_I2C_STM_OUT | 2 );  // 输出数据,位5-位0为长度,2字节
    mBuffer[ 3 ] = static_cast<UCHAR>( iDeviceAddr & 0xFE );  // 设备地址,写操作
    mBuffer[ 4 ] = static_cast<UCHAR>(iOutByte);  // I/O数据
    mBuffer[ 5 ] = mCH341A_CMD_I2C_STM_STO;  // 产生停止位
    mBuffer[ 6 ] = mCH341A_CMD_I2C_STM_END;  // 当前包提前结束
    mLength = 7;
    return( CH341WriteData( iIndex, mBuffer, &mLength ) );  // 写出数据块
}

BOOL WINAPI	PCF8574::IIC_OutByteCheckAck(  // 输出一字节数据并检查应答是否有效
    ULONG			iIndex,  // 指定CH341设备序号
    UCHAR			iOutByte )  // 准备写出的数据
{
    UCHAR	mBuffer[ mCH341_PACKET_LENGTH ];
    ULONG	mLength, mInLen;
    mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM;  // 命令码
    mBuffer[ 1 ] = mCH341A_CMD_I2C_STM_OUT;  // 输出数据,位5-位0为长度,0长度则只发送一个字节并返回应答
    mBuffer[ 2 ] = iOutByte;  // 数据
    mBuffer[ 3 ] = mCH341A_CMD_I2C_STM_STO;  // 产生停止位
    mBuffer[ 4 ] = mCH341A_CMD_I2C_STM_END;  // 当前包提前结束
    mLength = 5;
    mInLen = 0;
    if ( CH341WriteRead( iIndex, mLength, mBuffer, mCH341A_CMD_I2C_STM_MAX, 1, &mInLen, mBuffer ) ) {  // 执行数据流命令,先输出再输入
        if ( mInLen && ( mBuffer[ mInLen - 1 ] & 0x80 ) == 0 ) {
            return( TRUE );    // 返回的数据的位7代表ACK应答位,ACK=0有效
        }
    }
    return( FALSE );
}

BOOL WINAPI	PCF8574::IIC_IssueStop(
    ULONG			iIndex )  // 指定CH341设备序号
{
    UCHAR	mBuffer[ mCH341_PACKET_LENGTH ];
    ULONG	mLength;
    mBuffer[ 0 ] = mCH341A_CMD_I2C_STREAM;  // 命令码
    mBuffer[ 1 ] = mCH341A_CMD_I2C_STM_STO;  // 产生停止位
    mBuffer[ 2 ] = mCH341A_CMD_I2C_STM_END;  // 当前包提前结束
    mLength = 3;
    return( CH341WriteData( iIndex, mBuffer, &mLength ) );  // 写出数据块
}


